/**
 * \file zustand.h
 *
 * \brief Enthält die Klasse Zustand.
 */

#ifndef _ZUSTAND_H_
#define _ZUSTAND_H_

/** \class Zustand
*       \brief Die Klasse Zustand speichert den Zustand der Simulation, jedoch nicht die Daten.
*
*In Zustand ist gespeichert, welche Aktion vom Programm als nächstes auszuführen ist. Außerdem werden die Parameter für die jeweiligen Aktionen in dieser Klasse gespeichert.
*/

#include <string>
using namespace std;
#include "state.h"
#include "HeightWidth.h"

class Zustand
{
        private:
                volatile state zustand; /**< Im privaten Parameter zustand ist die nächste auszuführende, oder derzeit ausgeführte Aktion, gespeichert.*/

                //momentan nicht in gebrauch
                volatile bool inUse; /**< inUse dient als Lockvariable, da auf Objekte dieser Klasse von mehreren Threads zugegriffen wird.*/
                
                //problem: funktioniert nicht mit volatile
                string dateipfad;/**< Soll eine Simulation geladen oder gespeichert werden, ist der Pfad zur Datei als Parameter in dateipfad gespeichert.*/

                volatile int speed;/**< speed gibt die eingestellte geschwindigkeit der laufenden Simulation in Millisekunden an.*/
                volatile int realspeed;/**< realspeed gibt die wirkliche geschwindigkeit der laufenden Simulation in Millisekunden an.*/

                HeightWidth masse;/**< masse wird zur Festlegung der Feldgröße genutzt.*/

                volatile int anzahl;/**< anzahl dient zur Angabe der auszuführenden Einzelschritte.*/

                HeightWidth position;/**< position dient zur Beschreibung der Zelle, welche geändert werden soll, wenn der Nutzer die Feldbelegung selbst festlegen möchte.*/
        
                string beschreibung; /**<Die Beschreibung die mit einem Save gespeichert wird. */
                
                volatile bool regeln[2][9]; /**<Dient dem speichern der Parameter für das zu ändernde Regelwerk */
                
                volatile double rand; /**< Parameter für zufällige Belegung des Feldes */
				
				volatile int skip;	/**< Parameter zum Überspringen der Anzeige von Generationen */

        
        public:
                /**
                * \fn bool setState(state zustand)
                * \brief Setzt den aktuellen Zustand auf /a state, gibt bei erfolg true zurück, sonst false.
                * \param zustand Der zukünftige Zustand.
                */
                bool setState(state);
                
                /**
                *       \fn state getState()
                *       \brief Gibt den aktuellen Zustand des Systems zurück.
                */
                state getState();
                
                /**
                *       \fn void setPfad(string pfad)
                *       \brief Setzt den Parameter für die Aktionen Save und Load, den Pfad zur Datei.
                *       \param pfad Der Pfad zur Datei, in die gespeichert oder aus der geladen werden soll.
                */
                void setPfad(string);
                
                /**
                *       \fn string getPfad()
                *       \brief Gibt den Parameter Dateipfad zum Laden oder Speichern zurück.
                */
                string getPfad();
        
                /**
                *       \fn void setSpeed(int speed)
                *       \brief Setzt die Geschwindigkeit für die Simulation im laufenden Zustand.
                *       \param speed Die neue Geschwindigkeit.
                */
                void setSpeed(int);
                
                /**
                *       \fn int getSpeed()
                *       \brief  Gibt den aktuellen Wert für die Geschwindigkeit der laufenden Simulation zurück.
                */
                int getSpeed();
                
                
                
                /**
                *       \fn void setRealSpeed(unsigned long speed)
                *       \brief Setzt die Reale Geschwindigkeit (die das Programm wirklich benoetigt, um das naechste Bild anzuzeigen) für die Simulation im laufenden Zustand.
                *       \param speed Die neue Reale Geschwindigkeit.
                */
                void setRealSpeed(unsigned long);
                
                /**
                *       \fn int getRealSpeed()
                *       \brief  Gibt den aktuellen Wert für die Reale Geschwindigkeit der laufenden Simulation zurück.
                */
                int getRealSpeed();
                
                
                /**
                *       \fn void setMasse(HeightWidth masse)
                *       \brief Setzt den Parameter Höhe und Breite des Feldes für die Änderung der Feldgröße.
                *       \param masse Die neue Feldgröße.
                */
                void setMasse(HeightWidth);
                
                /**
                *       \fn HeightWidth getMasse()
                *       \brief Gibt die angestrebte neue Feldgröße zurück.
                */
                HeightWidth getMasse();

                /**
                *       \fn void setAnzahl(int anzahl)
                *       \brief Setzt die Anzahl an Einzelschritten, welche noch ausgeführt werden sollen.
                *       \param anzahl Noch auszuführende Zahl an Einzeschritten.
                */
                void setAnzahl(int);

                /**
                *       \fn int getAnzahl()
                *       \brief Gibt die noch verbleibende Anzahl an Einzelschritten zurück.
                */
                int getAnzahl();                

                /**             
                *       \fn void setPosition(HeightWidth position)
                *       \brief Setzt den Parameter Position, welcher benötigt wird, wenn der Benutzer den Wert einer speziellen Zelle verändern will.
                *       \param position Die Position der Zelle, welche geändert werden soll.
                */
                void setPosition(HeightWidth);          

                /**             
                *       \fn HeightWidth getPosition()   
                *       \brief Gibt die Position der Zelle zurück, welche der Nutzer ändern will.
                */
                HeightWidth getPosition();
                
                /**             
                *       \fn void setDescr(string descr)
                *       \brief Setzt den Parameter Beschreibung, welcher zum speichern benötigt wird.
                *       \param descr Die Beschreibung, welche einen Speicherstand beschreibt.
                */
                void setDescr(string);          

                /**             
                *       \fn string getDescr()
                *       \brief Gibt die Beschreibung zurück, die den Speicherstand beschreiben soll.
                */
                string getDescr();
                
                /**
                * \fn void setRule(bool vor, int lebNachbarn, bool nach)
                * \brief Setzt die Regel für den über die Parameter spezifizierten Fall, jedoch nur als Parameter in Zustand - die tatsächliche Änderung am Regelwerk führt der Aktionsmanager aus.
                * \param vor Der aktuelle Zustand der Zelle: false = tot, true = lebend.
                * \param lebNachbarn Die Anzahl der lebenden Nachbarn, für welche die Regel geändert werden soll.
                * \param nach Der Zustand, welchen eine Zelle in der nächsten Generation annehmen soll, wenn sie aktuell den Zustand vor und lebNachbarn viele lebende Nachbarn hat.
                */
                void setRule(bool, int, bool);
                
                /**
                * \fn bool getRule(bool vor, int lebNachbarn)
                * \brief Gibt den Wert der spezifizierten Regel aus. Dient nur als Parameter zum Ausführen der Regelwerksänderung. Zur Berechnung nutzt Feld das richtige Regelwerk.
                * \param vor Der aktuelle Zustand der Zelle: false = tot, true = lebend.
                * \param lebNachbarn Die Anzahl der lebenden Nachbarn, für welche die Regel abgefragt werden soll.
                * \return Der Zustand der Zelle in der nächsten Generation: 0=tot, 1=lebend.
                */
                bool getRule(bool, int);
                
                /**             
                *       \fn void setRand(double wkeit)
                *       \brief Setzt den Parameter Rand (Wahrscheinlichkeit für zufällige Feldbelegung).
                *       \param wkeit Die Wahrscheinlichkeit, dass eine Zelle leben wird.
                */
                void setRand(double);           

                /**             
                *       \fn double getRand()
                *       \brief Gibt die Wahrscheinlichkeit zurück, dass eine Zelle lebt.
                */
                double getRand();             

                /**             
                *       \fn void setSkip(int s)
                *       \brief Setzt den Parameter Skip.
                *       \param s Anzahl an Generationen, bis eine Anzeige erfolgt.
                */
                void setSkip(int);           

                /**             
                *       \fn int getSkip()
                *       \brief Gibt den Wert des Parameters Skip zurück.
                */
                int getSkip();     
				
                
                /**             
                *       \fn Zustand()
                *       \brief Der Konstruktor der Klasse Zustand.
                */
                Zustand();              
                
                /**             
                *       \fn ~Zustand()
                *       \brief Der Destruktor der Klasse Zustand.
                */
                ~Zustand();             
};

#endif
